home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / haltlib.lha / halt / unmount.c < prev    next >
C/C++ Source or Header  |  1995-10-06  |  3KB  |  154 lines

  1. /*
  2.    unmount.c --- unmount filesystems.
  3.  
  4.    (c) Copyright 1995 SHW Wabnitz
  5.    Written by Bernhard Fastenrath (fasten@shw.com)
  6.  
  7.    This file may be distributed under the terms
  8.    of the GNU General Public License.
  9. */
  10.  
  11. #include "halt_library.h"
  12.  
  13. static void
  14. FreeList (List *list)
  15. {
  16.   Node *node, *next;
  17.  
  18.   for (next = node = list -> lh_Head; next -> ln_Succ; node = next)
  19.   {
  20.     next = node -> ln_Succ;
  21.     if (node -> ln_Name)
  22.       FreeMem (node -> ln_Name, node -> ln_Pri);
  23.     FreeMem (node, sizeof (Node));
  24.   }
  25. }
  26.  
  27. static int
  28. PingPong (MsgPort *from, MsgPort *to, StandardPacket *sp,
  29.       ULONG action, ULONG arg)
  30. {
  31.   sp -> sp_Msg.mn_Node.ln_Name = (char *) &sp -> sp_Pkt;
  32.   sp -> sp_Pkt.dp_Link = &sp -> sp_Msg;
  33.   sp -> sp_Pkt.dp_Port = from;
  34.   sp -> sp_Pkt.dp_Type = action;
  35.   sp -> sp_Pkt.dp_Arg1 = arg;
  36.   PutMsg (to, &sp -> sp_Msg);
  37.   do
  38.     WaitPort (from);
  39.   while (!GetMsg (from));
  40.   return 1;
  41. }
  42.  
  43. static int
  44. SendToHandler (MsgPort *mp, ULONG ptype, char *handler, ULONG arg)
  45. {
  46.   DevProc *dp = NULL;
  47.   StandardPacket sp;
  48.   int ret = 0;
  49.  
  50.   dp = GetDeviceProc (handler, dp);
  51.   if (dp)
  52.   {
  53.     PingPong (mp, dp -> dvp_Port, &sp, ACTION_IS_FILESYSTEM, 0);
  54.     if (sp.sp_Pkt.dp_Res1 == DOSTRUE)
  55.     {
  56.       PingPong (mp, dp -> dvp_Port, &sp, ptype, arg);
  57.       ret = 1;
  58.     }
  59.     else
  60.       ret = -1;
  61.   }
  62.   FreeDeviceProc (dp);
  63.   return ret;
  64. }
  65.  
  66. static int
  67. SendToAll (MsgPort *mp, ULONG ptype, ULONG arg)
  68. {
  69.   List list;
  70.   Node *node;
  71.   DosInfo *di;
  72.   DeviceNode *dn;
  73.   int len, out_of_mem = 0;
  74.   char *name;
  75.   BPTR *pdn;
  76.   int ret;
  77.  
  78.   NewList (&list);
  79.   Forbid ();
  80.   di = BADDR (((RootNode *) DOSBase -> dl_Root) -> rn_Info);
  81.   for (pdn = &di -> di_DevInfo; dn = (DeviceNode *) BADDR (*pdn);
  82.        pdn = &dn -> dn_Next)
  83.   {
  84.     if (dn -> dn_Type == DLT_DEVICE)
  85.     {
  86.       if (node = (Node *) AllocMem (sizeof (Node), MEMF_CLEAR))
  87.       {
  88.     name = BADDR (dn -> dn_Name);
  89.     len = (int) name[0];
  90.     if (node -> ln_Name = AllocMem (len + 2, 0))
  91.     {
  92.       CopyMem (name+1, node -> ln_Name, len);
  93.       node -> ln_Name[len] = ':';
  94.       node -> ln_Name[len+1] = '\0';
  95.       node -> ln_Pri = len + 2;
  96.       AddTail (&list, node);
  97.     }
  98.     else
  99.     {
  100.       out_of_mem = 1;
  101.       FreeMem (node, sizeof (Node));
  102.       break;
  103.     }
  104.       }
  105.       else
  106.       {
  107.     out_of_mem = 1;
  108.     break;
  109.       }
  110.     }
  111.   }
  112.   Permit ();
  113.  
  114.   if (out_of_mem)
  115.   {
  116.     FreeList (&list);
  117.     return 0;
  118.   }
  119.  
  120.   len = 0;
  121.   for (node = list.lh_Head; node -> ln_Succ; node = node -> ln_Succ)
  122.     ret = SendToHandler (mp, ptype, node -> ln_Name, arg);
  123.   FreeList (&list);
  124.   return 1;
  125. }
  126.  
  127. /*** public functions ***/
  128.  
  129. int
  130. unmount (MsgPort *mp, char *filesystem)
  131. {
  132.   ULONG arg = DOSTRUE, ptype = ACTION_INHIBIT; 
  133.   int free_port = 0, ret;
  134.  
  135.   if (!mp)
  136.   {
  137.     if (!(mp = CreatePort (NULL, 0)))
  138.       return 0;
  139.     free_port = 1;
  140.   }
  141.   if (filesystem)
  142.   {
  143.     ret = SendToHandler (mp, ptype, filesystem, arg);
  144.   }
  145.   else
  146.   {
  147.     ret = SendToAll (mp, ptype, arg);
  148.   }
  149.   if (free_port)
  150.     DeletePort (mp);
  151.   return ret;
  152. }
  153.  
  154.